{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Execute this cell to install dependencies\n",
    "%pip install sf-hamilton[visualization] polars"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Polars integration tutorial [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/dagworks-inc/hamilton/blob/main/examples/polars/materialization/notebook.ipynb) [![GitHub badge](https://img.shields.io/badge/github-view_source-2b3137?logo=github)](https://github.com/apache/hamilton/blob/main/examples/polars/materialization/notebook.ipynb)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-05T16:36:35.401649Z",
     "start_time": "2023-10-05T16:36:33.838727Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "d:\\Turing\\codes\\hamilton\\venv\\lib\\site-packages\\pyspark\\pandas\\__init__.py:50: UserWarning: 'PYARROW_IGNORE_TIMEZONE' environment variable was not set. It is required to set this environment variable to '1' in both driver and executor sides if you use pyarrow>=2.0.0. pandas-on-Spark will set it for you but it does not work if there is a Spark context already launched.\n",
      "  warnings.warn(\n"
     ]
    }
   ],
   "source": [
    "import polars as pl\n",
    "import sys\n",
    "# Add the hamilton module to your path - optinal\n",
    "# project_dir = \"### ADD PATH HERE ###\"\n",
    "# sys.path.append(project_dir)\n",
    "\n",
    "from hamilton import driver\n",
    "from hamilton.io.materialization import to\n",
    "from hamilton.plugins import h_polars"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-05T16:36:35.465307Z",
     "start_time": "2023-10-05T16:36:35.406399Z"
    },
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "# We use the autoreload extension that comes with ipython to automatically reload modules when\n",
    "# the code in them changes.\n",
    "\n",
    "# import the jupyter extension\n",
    "%load_ext autoreload\n",
    "# set it to only reload the modules imported\n",
    "%autoreload 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-05T16:36:36.389233Z",
     "start_time": "2023-10-05T16:36:36.380788Z"
    },
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Writing spend_calculations.py\n"
     ]
    }
   ],
   "source": [
    "%%writefile spend_calculations.py\n",
    "# Define your new Hamilton functions.\n",
    "# The %%writefile magic command creates a new Python module with the functions below.\n",
    "# We will import this later and pass it into our Driver.\n",
    "\n",
    "import polars as pl\n",
    "\n",
    "# Look at `my_functions` to see how these functions connect.\n",
    "def avg_3wk_spend(spend: pl.Series) -> pl.Series:\n",
    "    \"\"\"Rolling 3 week average spend.\"\"\"\n",
    "    return spend.rolling_mean(3)\n",
    "\n",
    "\n",
    "def spend_per_signup(spend: pl.Series, signups: pl.Series) -> pl.Series:\n",
    "    \"\"\"The cost per signup in relation to spend.\"\"\"\n",
    "    return spend / signups\n",
    "\n",
    "\n",
    "def spend_mean(spend: pl.Series) -> float:\n",
    "    \"\"\"Shows function creating a scalar. In this case it computes the mean of the entire column.\"\"\"\n",
    "    return spend.mean()\n",
    "\n",
    "\n",
    "def spend_zero_mean(spend: pl.Series, spend_mean: float) -> pl.Series:\n",
    "    \"\"\"Shows function that takes a scalar. In this case to zero mean spend.\"\"\"\n",
    "    return spend - spend_mean\n",
    "\n",
    "\n",
    "def spend_std_dev(spend: pl.Series) -> float:\n",
    "    \"\"\"Function that computes the standard deviation of the spend column.\"\"\"\n",
    "    return spend.std()\n",
    "\n",
    "\n",
    "def spend_zero_mean_unit_variance(spend_zero_mean: pl.Series, spend_std_dev: float) -> pl.Series:\n",
    "    \"\"\"Function showing one way to make spend have zero mean and unit variance.\"\"\"\n",
    "    return spend_zero_mean / spend_std_dev"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-05T16:36:36.947063Z",
     "start_time": "2023-10-05T16:36:36.938015Z"
    },
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "initial_columns = {  # load from actuals or wherever -- this is our initial data we use as input.\n",
    "    # Note: these values don't have to be all series, they could be a scalar.\n",
    "    \"signups\": pl.Series([1, 10, 50, 100, 200, 400]),\n",
    "    \"spend\": pl.Series([10, 10, 20, 40, 40, 50]),\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-05T16:36:37.496013Z",
     "start_time": "2023-10-05T16:36:37.447521Z"
    },
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "%aimport spend_calculations\n",
    "\n",
    "df_builder = h_polars.PolarsDataFrameResult()\n",
    "dr = driver.Driver({}, spend_calculations)  # can pass in multiple modules"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-05T16:36:38.178430Z",
     "start_time": "2023-10-05T16:36:38.162359Z"
    }
   },
   "outputs": [],
   "source": [
    "# we need to specify what we want in the final dataframe. These can be string names, or function references.\n",
    "output_columns = [\n",
    "    \"spend\",\n",
    "    \"signups\",\n",
    "    \"avg_3wk_spend\",\n",
    "    \"spend_per_signup\",\n",
    "    \"spend_zero_mean_unit_variance\",\n",
    "]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-05T16:36:39.212897Z",
     "start_time": "2023-10-05T16:36:39.202499Z"
    },
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-05T16:36:39.908587Z",
     "start_time": "2023-10-05T16:36:39.637374Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 10.0.1 (20240210.2158)\n",
       " -->\n",
       "<!-- Pages: 1 -->\n",
       "<svg width=\"1223pt\" height=\"752pt\"\n",
       " viewBox=\"0.00 0.00 1222.60 751.60\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 747.6)\">\n",
       "<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-747.6 1218.6,-747.6 1218.6,4 -4,4\"/>\n",
       "<g id=\"clust1\" class=\"cluster\">\n",
       "<title>cluster__legend</title>\n",
       "<polygon fill=\"#ffffff\" stroke=\"black\" points=\"8,-303.8 8,-554.8 117.6,-554.8 117.6,-303.8 8,-303.8\"/>\n",
       "<text text-anchor=\"middle\" x=\"62.8\" y=\"-537.5\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">Legend</text>\n",
       "</g>\n",
       "<!-- spend_mean -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>spend_mean</title>\n",
       "<path fill=\"#b4d8e4\" stroke=\"black\" d=\"M252.2,-302.6C252.2,-302.6 164.6,-302.6 164.6,-302.6 158.6,-302.6 152.6,-296.6 152.6,-290.6 152.6,-290.6 152.6,-251 152.6,-251 152.6,-245 158.6,-239 164.6,-239 164.6,-239 252.2,-239 252.2,-239 258.2,-239 264.2,-245 264.2,-251 264.2,-251 264.2,-290.6 264.2,-290.6 264.2,-296.6 258.2,-302.6 252.2,-302.6\"/>\n",
       "<text text-anchor=\"start\" x=\"163.4\" y=\"-279.5\" font-family=\"Helvetica,sans-Serif\" font-weight=\"bold\" font-size=\"14.00\">spend_mean</text>\n",
       "<text text-anchor=\"start\" x=\"194.52\" y=\"-251.5\" font-family=\"Helvetica,sans-Serif\" font-style=\"italic\" font-size=\"14.00\">float</text>\n",
       "</g>\n",
       "<!-- spend_zero_mean -->\n",
       "<g id=\"node17\" class=\"node\">\n",
       "<title>spend_zero_mean</title>\n",
       "<path fill=\"#b4d8e4\" stroke=\"black\" d=\"M434.3,-366.6C434.3,-366.6 307.7,-366.6 307.7,-366.6 301.7,-366.6 295.7,-360.6 295.7,-354.6 295.7,-354.6 295.7,-315 295.7,-315 295.7,-309 301.7,-303 307.7,-303 307.7,-303 434.3,-303 434.3,-303 440.3,-303 446.3,-309 446.3,-315 446.3,-315 446.3,-354.6 446.3,-354.6 446.3,-360.6 440.3,-366.6 434.3,-366.6\"/>\n",
       "<text text-anchor=\"start\" x=\"306.5\" y=\"-343.5\" font-family=\"Helvetica,sans-Serif\" font-weight=\"bold\" font-size=\"14.00\">spend_zero_mean</text>\n",
       "<text text-anchor=\"start\" x=\"350\" y=\"-315.5\" font-family=\"Helvetica,sans-Serif\" font-style=\"italic\" font-size=\"14.00\">Series</text>\n",
       "</g>\n",
       "<!-- spend_mean&#45;&gt;spend_zero_mean -->\n",
       "<g id=\"edge36\" class=\"edge\">\n",
       "<title>spend_mean&#45;&gt;spend_zero_mean</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M264.67,-292.83C271.16,-295.41 277.89,-298.09 284.67,-300.8\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"283.35,-304.04 293.93,-304.49 285.94,-297.53 283.35,-304.04\"/>\n",
       "</g>\n",
       "<!-- df_to_feather -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>df_to_feather</title>\n",
       "<path fill=\"#ffc857\" stroke=\"black\" d=\"M1198.1,-565.57C1198.1,-569.96 1164.01,-573.52 1122.05,-573.52 1080.09,-573.52 1046,-569.96 1046,-565.57 1046,-565.57 1046,-494.02 1046,-494.02 1046,-489.64 1080.09,-486.07 1122.05,-486.07 1164.01,-486.07 1198.1,-489.64 1198.1,-494.02 1198.1,-494.02 1198.1,-565.57 1198.1,-565.57\"/>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M1198.1,-565.57C1198.1,-561.19 1164.01,-557.62 1122.05,-557.62 1080.09,-557.62 1046,-561.19 1046,-565.57\"/>\n",
       "<text text-anchor=\"start\" x=\"1075.92\" y=\"-538.5\" font-family=\"Helvetica,sans-Serif\" font-weight=\"bold\" font-size=\"14.00\">df_to_feather</text>\n",
       "<text text-anchor=\"start\" x=\"1056.8\" y=\"-510.5\" font-family=\"Helvetica,sans-Serif\" font-style=\"italic\" font-size=\"14.00\">PolarsFeatherWriter</text>\n",
       "</g>\n",
       "<!-- avg_3wk_spend -->\n",
       "<g id=\"node3\" class=\"node\">\n",
       "<title>avg_3wk_spend</title>\n",
       "<path fill=\"#ffc857\" stroke=\"black\" d=\"M657.4,-485.6C657.4,-485.6 546.55,-485.6 546.55,-485.6 540.55,-485.6 534.55,-479.6 534.55,-473.6 534.55,-473.6 534.55,-434 534.55,-434 534.55,-428 540.55,-422 546.55,-422 546.55,-422 657.4,-422 657.4,-422 663.4,-422 669.4,-428 669.4,-434 669.4,-434 669.4,-473.6 669.4,-473.6 669.4,-479.6 663.4,-485.6 657.4,-485.6\"/>\n",
       "<text text-anchor=\"start\" x=\"545.35\" y=\"-462.5\" font-family=\"Helvetica,sans-Serif\" font-weight=\"bold\" font-size=\"14.00\">avg_3wk_spend</text>\n",
       "<text text-anchor=\"start\" x=\"580.97\" y=\"-434.5\" font-family=\"Helvetica,sans-Serif\" font-style=\"italic\" font-size=\"14.00\">Series</text>\n",
       "</g>\n",
       "<!-- df_to_json_build_result -->\n",
       "<g id=\"node4\" class=\"node\">\n",
       "<title>df_to_json_build_result</title>\n",
       "<path fill=\"#b4d8e4\" stroke=\"black\" d=\"M960,-608.6C960,-608.6 798.15,-608.6 798.15,-608.6 792.15,-608.6 786.15,-602.6 786.15,-596.6 786.15,-596.6 786.15,-557 786.15,-557 786.15,-551 792.15,-545 798.15,-545 798.15,-545 960,-545 960,-545 966,-545 972,-551 972,-557 972,-557 972,-596.6 972,-596.6 972,-602.6 966,-608.6 960,-608.6\"/>\n",
       "<text text-anchor=\"start\" x=\"796.95\" y=\"-585.5\" font-family=\"Helvetica,sans-Serif\" font-weight=\"bold\" font-size=\"14.00\">df_to_json_build_result</text>\n",
       "<text text-anchor=\"start\" x=\"842.32\" y=\"-557.5\" font-family=\"Helvetica,sans-Serif\" font-style=\"italic\" font-size=\"14.00\">DataFrame</text>\n",
       "</g>\n",
       "<!-- avg_3wk_spend&#45;&gt;df_to_json_build_result -->\n",
       "<g id=\"edge4\" class=\"edge\">\n",
       "<title>avg_3wk_spend&#45;&gt;df_to_json_build_result</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M669.72,-467C689.96,-473.17 711.38,-482.07 728.65,-494.8 746.62,-508.04 739.77,-522.44 757.65,-535.8 763.28,-540.01 769.37,-543.8 775.73,-547.22\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"774.03,-550.29 784.54,-551.62 777.15,-544.02 774.03,-550.29\"/>\n",
       "</g>\n",
       "<!-- df_to_database_build_result -->\n",
       "<g id=\"node6\" class=\"node\">\n",
       "<title>df_to_database_build_result</title>\n",
       "<path fill=\"#b4d8e4\" stroke=\"black\" d=\"M976.87,-444.6C976.87,-444.6 781.27,-444.6 781.27,-444.6 775.27,-444.6 769.27,-438.6 769.27,-432.6 769.27,-432.6 769.27,-393 769.27,-393 769.27,-387 775.27,-381 781.27,-381 781.27,-381 976.87,-381 976.87,-381 982.87,-381 988.87,-387 988.87,-393 988.87,-393 988.87,-432.6 988.87,-432.6 988.87,-438.6 982.87,-444.6 976.87,-444.6\"/>\n",
       "<text text-anchor=\"start\" x=\"780.07\" y=\"-421.5\" font-family=\"Helvetica,sans-Serif\" font-weight=\"bold\" font-size=\"14.00\">df_to_database_build_result</text>\n",
       "<text text-anchor=\"start\" x=\"842.32\" y=\"-393.5\" font-family=\"Helvetica,sans-Serif\" font-style=\"italic\" font-size=\"14.00\">DataFrame</text>\n",
       "</g>\n",
       "<!-- avg_3wk_spend&#45;&gt;df_to_database_build_result -->\n",
       "<g id=\"edge9\" class=\"edge\">\n",
       "<title>avg_3wk_spend&#45;&gt;df_to_database_build_result</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M669.57,-443.88C696.12,-439.92 727.54,-435.24 757.81,-430.72\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"758.03,-434.23 767.41,-429.29 757,-427.31 758.03,-434.23\"/>\n",
       "</g>\n",
       "<!-- df_to_feather_build_result -->\n",
       "<g id=\"node7\" class=\"node\">\n",
       "<title>df_to_feather_build_result</title>\n",
       "<path fill=\"#b4d8e4\" stroke=\"black\" d=\"M969.37,-526.6C969.37,-526.6 788.77,-526.6 788.77,-526.6 782.77,-526.6 776.77,-520.6 776.77,-514.6 776.77,-514.6 776.77,-475 776.77,-475 776.77,-469 782.77,-463 788.77,-463 788.77,-463 969.37,-463 969.37,-463 975.37,-463 981.37,-469 981.37,-475 981.37,-475 981.37,-514.6 981.37,-514.6 981.37,-520.6 975.37,-526.6 969.37,-526.6\"/>\n",
       "<text text-anchor=\"start\" x=\"787.57\" y=\"-503.5\" font-family=\"Helvetica,sans-Serif\" font-weight=\"bold\" font-size=\"14.00\">df_to_feather_build_result</text>\n",
       "<text text-anchor=\"start\" x=\"842.32\" y=\"-475.5\" font-family=\"Helvetica,sans-Serif\" font-style=\"italic\" font-size=\"14.00\">DataFrame</text>\n",
       "</g>\n",
       "<!-- avg_3wk_spend&#45;&gt;df_to_feather_build_result -->\n",
       "<g id=\"edge13\" class=\"edge\">\n",
       "<title>avg_3wk_spend&#45;&gt;df_to_feather_build_result</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M669.57,-463.72C698.23,-468 732.55,-473.11 765,-477.95\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"764.48,-481.41 774.89,-479.42 765.51,-474.49 764.48,-481.41\"/>\n",
       "</g>\n",
       "<!-- df_to_parquet_build_result -->\n",
       "<g id=\"node10\" class=\"node\">\n",
       "<title>df_to_parquet_build_result</title>\n",
       "<path fill=\"#b4d8e4\" stroke=\"black\" d=\"M972,-362.6C972,-362.6 786.15,-362.6 786.15,-362.6 780.15,-362.6 774.15,-356.6 774.15,-350.6 774.15,-350.6 774.15,-311 774.15,-311 774.15,-305 780.15,-299 786.15,-299 786.15,-299 972,-299 972,-299 978,-299 984,-305 984,-311 984,-311 984,-350.6 984,-350.6 984,-356.6 978,-362.6 972,-362.6\"/>\n",
       "<text text-anchor=\"start\" x=\"784.95\" y=\"-339.5\" font-family=\"Helvetica,sans-Serif\" font-weight=\"bold\" font-size=\"14.00\">df_to_parquet_build_result</text>\n",
       "<text text-anchor=\"start\" x=\"842.32\" y=\"-311.5\" font-family=\"Helvetica,sans-Serif\" font-style=\"italic\" font-size=\"14.00\">DataFrame</text>\n",
       "</g>\n",
       "<!-- avg_3wk_spend&#45;&gt;df_to_parquet_build_result -->\n",
       "<g id=\"edge19\" class=\"edge\">\n",
       "<title>avg_3wk_spend&#45;&gt;df_to_parquet_build_result</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M669.72,-440.6C689.96,-434.43 711.38,-425.53 728.65,-412.8 746.62,-399.56 739.77,-385.16 757.65,-371.8 759.7,-370.27 761.81,-368.79 763.97,-367.37\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"765.7,-370.41 772.45,-362.25 762.08,-364.42 765.7,-370.41\"/>\n",
       "</g>\n",
       "<!-- df_to_spreadsheet_build_result -->\n",
       "<g id=\"node13\" class=\"node\">\n",
       "<title>df_to_spreadsheet_build_result</title>\n",
       "<path fill=\"#b4d8e4\" stroke=\"black\" d=\"M988.5,-198.6C988.5,-198.6 769.65,-198.6 769.65,-198.6 763.65,-198.6 757.65,-192.6 757.65,-186.6 757.65,-186.6 757.65,-147 757.65,-147 757.65,-141 763.65,-135 769.65,-135 769.65,-135 988.5,-135 988.5,-135 994.5,-135 1000.5,-141 1000.5,-147 1000.5,-147 1000.5,-186.6 1000.5,-186.6 1000.5,-192.6 994.5,-198.6 988.5,-198.6\"/>\n",
       "<text text-anchor=\"start\" x=\"768.45\" y=\"-175.5\" font-family=\"Helvetica,sans-Serif\" font-weight=\"bold\" font-size=\"14.00\">df_to_spreadsheet_build_result</text>\n",
       "<text text-anchor=\"start\" x=\"842.32\" y=\"-147.5\" font-family=\"Helvetica,sans-Serif\" font-style=\"italic\" font-size=\"14.00\">DataFrame</text>\n",
       "</g>\n",
       "<!-- avg_3wk_spend&#45;&gt;df_to_spreadsheet_build_result -->\n",
       "<g id=\"edge25\" class=\"edge\">\n",
       "<title>avg_3wk_spend&#45;&gt;df_to_spreadsheet_build_result</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M669.67,-446.27C691.5,-440.49 713.9,-430.38 728.65,-412.8 787.79,-342.3 698.96,-278.68 757.65,-207.8 757.9,-207.5 758.15,-207.2 758.41,-206.9\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"760.78,-209.48 765.36,-199.92 755.82,-204.54 760.78,-209.48\"/>\n",
       "</g>\n",
       "<!-- df_to_avro_build_result -->\n",
       "<g id=\"node14\" class=\"node\">\n",
       "<title>df_to_avro_build_result</title>\n",
       "<path fill=\"#b4d8e4\" stroke=\"black\" d=\"M960.75,-280.6C960.75,-280.6 797.4,-280.6 797.4,-280.6 791.4,-280.6 785.4,-274.6 785.4,-268.6 785.4,-268.6 785.4,-229 785.4,-229 785.4,-223 791.4,-217 797.4,-217 797.4,-217 960.75,-217 960.75,-217 966.75,-217 972.75,-223 972.75,-229 972.75,-229 972.75,-268.6 972.75,-268.6 972.75,-274.6 966.75,-280.6 960.75,-280.6\"/>\n",
       "<text text-anchor=\"start\" x=\"796.2\" y=\"-257.5\" font-family=\"Helvetica,sans-Serif\" font-weight=\"bold\" font-size=\"14.00\">df_to_avro_build_result</text>\n",
       "<text text-anchor=\"start\" x=\"842.32\" y=\"-229.5\" font-family=\"Helvetica,sans-Serif\" font-style=\"italic\" font-size=\"14.00\">DataFrame</text>\n",
       "</g>\n",
       "<!-- avg_3wk_spend&#45;&gt;df_to_avro_build_result -->\n",
       "<g id=\"edge29\" class=\"edge\">\n",
       "<title>avg_3wk_spend&#45;&gt;df_to_avro_build_result</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M669.78,-445.23C691.22,-439.35 713.35,-429.44 728.65,-412.8 766.67,-371.46 719.9,-331.39 757.65,-289.8 762.79,-284.14 768.73,-279.26 775.18,-275.06\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"776.76,-278.19 783.64,-270.13 773.24,-272.14 776.76,-278.19\"/>\n",
       "</g>\n",
       "<!-- df_to_json -->\n",
       "<g id=\"node11\" class=\"node\">\n",
       "<title>df_to_json</title>\n",
       "<path fill=\"#ffc857\" stroke=\"black\" d=\"M1192.47,-670.57C1192.47,-674.96 1160.91,-678.52 1122.05,-678.52 1083.19,-678.52 1051.62,-674.96 1051.62,-670.57 1051.62,-670.57 1051.62,-599.02 1051.62,-599.02 1051.62,-594.64 1083.19,-591.07 1122.05,-591.07 1160.91,-591.07 1192.47,-594.64 1192.47,-599.02 1192.47,-599.02 1192.47,-670.57 1192.47,-670.57\"/>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M1192.47,-670.57C1192.47,-666.19 1160.91,-662.62 1122.05,-662.62 1083.19,-662.62 1051.62,-666.19 1051.62,-670.57\"/>\n",
       "<text text-anchor=\"start\" x=\"1085.3\" y=\"-643.5\" font-family=\"Helvetica,sans-Serif\" font-weight=\"bold\" font-size=\"14.00\">df_to_json</text>\n",
       "<text text-anchor=\"start\" x=\"1062.42\" y=\"-615.5\" font-family=\"Helvetica,sans-Serif\" font-style=\"italic\" font-size=\"14.00\">PolarsJSONWriter</text>\n",
       "</g>\n",
       "<!-- df_to_json_build_result&#45;&gt;df_to_json -->\n",
       "<g id=\"edge23\" class=\"edge\">\n",
       "<title>df_to_json_build_result&#45;&gt;df_to_json</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M972.21,-598.98C994.71,-604.39 1018.62,-610.15 1040.53,-615.42\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"1039.44,-618.76 1049.98,-617.7 1041.08,-611.95 1039.44,-618.76\"/>\n",
       "</g>\n",
       "<!-- df_to_parquet -->\n",
       "<g id=\"node5\" class=\"node\">\n",
       "<title>df_to_parquet</title>\n",
       "<path fill=\"#ffc857\" stroke=\"black\" d=\"M1198.47,-355.57C1198.47,-359.96 1164.22,-363.52 1122.05,-363.52 1079.88,-363.52 1045.62,-359.96 1045.62,-355.57 1045.62,-355.57 1045.62,-284.03 1045.62,-284.03 1045.62,-279.64 1079.88,-276.08 1122.05,-276.08 1164.22,-276.08 1198.47,-279.64 1198.47,-284.03 1198.47,-284.03 1198.47,-355.57 1198.47,-355.57\"/>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M1198.47,-355.57C1198.47,-351.19 1164.22,-347.62 1122.05,-347.62 1079.88,-347.62 1045.62,-351.19 1045.62,-355.57\"/>\n",
       "<text text-anchor=\"start\" x=\"1073.3\" y=\"-328.5\" font-family=\"Helvetica,sans-Serif\" font-weight=\"bold\" font-size=\"14.00\">df_to_parquet</text>\n",
       "<text text-anchor=\"start\" x=\"1056.42\" y=\"-300.5\" font-family=\"Helvetica,sans-Serif\" font-style=\"italic\" font-size=\"14.00\">PolarsParquetWriter</text>\n",
       "</g>\n",
       "<!-- df_to_database -->\n",
       "<g id=\"node15\" class=\"node\">\n",
       "<title>df_to_database</title>\n",
       "<path fill=\"#ffc857\" stroke=\"black\" d=\"M1204.47,-460.57C1204.47,-464.96 1167.53,-468.52 1122.05,-468.52 1076.57,-468.52 1039.62,-464.96 1039.62,-460.57 1039.62,-460.57 1039.62,-389.03 1039.62,-389.03 1039.62,-384.64 1076.57,-381.08 1122.05,-381.08 1167.53,-381.08 1204.47,-384.64 1204.47,-389.03 1204.47,-389.03 1204.47,-460.57 1204.47,-460.57\"/>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M1204.47,-460.57C1204.47,-456.19 1167.53,-452.62 1122.05,-452.62 1076.57,-452.62 1039.62,-456.19 1039.62,-460.57\"/>\n",
       "<text text-anchor=\"start\" x=\"1068.42\" y=\"-433.5\" font-family=\"Helvetica,sans-Serif\" font-weight=\"bold\" font-size=\"14.00\">df_to_database</text>\n",
       "<text text-anchor=\"start\" x=\"1050.42\" y=\"-405.5\" font-family=\"Helvetica,sans-Serif\" font-style=\"italic\" font-size=\"14.00\">PolarsDatabaseWriter</text>\n",
       "</g>\n",
       "<!-- df_to_database_build_result&#45;&gt;df_to_database -->\n",
       "<g id=\"edge33\" class=\"edge\">\n",
       "<title>df_to_database_build_result&#45;&gt;df_to_database</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M989.28,-418.24C1002.15,-418.88 1015.2,-419.53 1027.82,-420.16\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"1027.6,-423.65 1037.77,-420.65 1027.95,-416.66 1027.6,-423.65\"/>\n",
       "</g>\n",
       "<!-- df_to_feather_build_result&#45;&gt;df_to_feather -->\n",
       "<g id=\"edge2\" class=\"edge\">\n",
       "<title>df_to_feather_build_result&#45;&gt;df_to_feather</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M981.57,-509.54C999.19,-512.1 1017.37,-514.74 1034.54,-517.24\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"1033.77,-520.66 1044.17,-518.63 1034.78,-513.73 1033.77,-520.66\"/>\n",
       "</g>\n",
       "<!-- df_to_spreadsheet -->\n",
       "<g id=\"node8\" class=\"node\">\n",
       "<title>df_to_spreadsheet</title>\n",
       "<path fill=\"#ffc857\" stroke=\"black\" d=\"M1214.6,-145.57C1214.6,-149.96 1173.12,-153.53 1122.05,-153.53 1070.98,-153.53 1029.5,-149.96 1029.5,-145.57 1029.5,-145.57 1029.5,-74.03 1029.5,-74.03 1029.5,-69.64 1070.98,-66.08 1122.05,-66.08 1173.12,-66.08 1214.6,-69.64 1214.6,-74.03 1214.6,-74.03 1214.6,-145.57 1214.6,-145.57\"/>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M1214.6,-145.57C1214.6,-141.19 1173.12,-137.62 1122.05,-137.62 1070.98,-137.62 1029.5,-141.19 1029.5,-145.57\"/>\n",
       "<text text-anchor=\"start\" x=\"1056.8\" y=\"-118.5\" font-family=\"Helvetica,sans-Serif\" font-weight=\"bold\" font-size=\"14.00\">df_to_spreadsheet</text>\n",
       "<text text-anchor=\"start\" x=\"1040.3\" y=\"-90.5\" font-family=\"Helvetica,sans-Serif\" font-style=\"italic\" font-size=\"14.00\">PolarsSpreadsheetWriter</text>\n",
       "</g>\n",
       "<!-- df_to_avro -->\n",
       "<g id=\"node9\" class=\"node\">\n",
       "<title>df_to_avro</title>\n",
       "<path fill=\"#ffc857\" stroke=\"black\" d=\"M1187.97,-250.57C1187.97,-254.96 1158.43,-258.52 1122.05,-258.52 1085.67,-258.52 1056.12,-254.96 1056.12,-250.57 1056.12,-250.57 1056.12,-179.03 1056.12,-179.03 1056.12,-174.64 1085.67,-171.08 1122.05,-171.08 1158.43,-171.08 1187.97,-174.64 1187.97,-179.03 1187.97,-179.03 1187.97,-250.57 1187.97,-250.57\"/>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M1187.97,-250.57C1187.97,-246.19 1158.43,-242.62 1122.05,-242.62 1085.67,-242.62 1056.12,-246.19 1056.12,-250.57\"/>\n",
       "<text text-anchor=\"start\" x=\"1084.55\" y=\"-223.5\" font-family=\"Helvetica,sans-Serif\" font-weight=\"bold\" font-size=\"14.00\">df_to_avro</text>\n",
       "<text text-anchor=\"start\" x=\"1066.92\" y=\"-195.5\" font-family=\"Helvetica,sans-Serif\" font-style=\"italic\" font-size=\"14.00\">PolarsAvroWriter</text>\n",
       "</g>\n",
       "<!-- df_to_parquet_build_result&#45;&gt;df_to_parquet -->\n",
       "<g id=\"edge8\" class=\"edge\">\n",
       "<title>df_to_parquet_build_result&#45;&gt;df_to_parquet</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M984.37,-326.04C1001.01,-325.28 1018.07,-324.5 1034.24,-323.76\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"1033.95,-327.28 1043.78,-323.33 1033.63,-320.29 1033.95,-327.28\"/>\n",
       "</g>\n",
       "<!-- spend_std_dev -->\n",
       "<g id=\"node12\" class=\"node\">\n",
       "<title>spend_std_dev</title>\n",
       "<path fill=\"#b4d8e4\" stroke=\"black\" d=\"M423.42,-448.6C423.42,-448.6 318.57,-448.6 318.57,-448.6 312.57,-448.6 306.57,-442.6 306.57,-436.6 306.57,-436.6 306.57,-397 306.57,-397 306.57,-391 312.57,-385 318.57,-385 318.57,-385 423.42,-385 423.42,-385 429.42,-385 435.42,-391 435.42,-397 435.42,-397 435.42,-436.6 435.42,-436.6 435.42,-442.6 429.42,-448.6 423.42,-448.6\"/>\n",
       "<text text-anchor=\"start\" x=\"317.37\" y=\"-425.5\" font-family=\"Helvetica,sans-Serif\" font-weight=\"bold\" font-size=\"14.00\">spend_std_dev</text>\n",
       "<text text-anchor=\"start\" x=\"357.12\" y=\"-397.5\" font-family=\"Helvetica,sans-Serif\" font-style=\"italic\" font-size=\"14.00\">float</text>\n",
       "</g>\n",
       "<!-- spend_zero_mean_unit_variance -->\n",
       "<g id=\"node16\" class=\"node\">\n",
       "<title>spend_zero_mean_unit_variance</title>\n",
       "<path fill=\"#ffc857\" stroke=\"black\" d=\"M716.65,-403.6C716.65,-403.6 487.3,-403.6 487.3,-403.6 481.3,-403.6 475.3,-397.6 475.3,-391.6 475.3,-391.6 475.3,-352 475.3,-352 475.3,-346 481.3,-340 487.3,-340 487.3,-340 716.65,-340 716.65,-340 722.65,-340 728.65,-346 728.65,-352 728.65,-352 728.65,-391.6 728.65,-391.6 728.65,-397.6 722.65,-403.6 716.65,-403.6\"/>\n",
       "<text text-anchor=\"start\" x=\"486.1\" y=\"-380.5\" font-family=\"Helvetica,sans-Serif\" font-weight=\"bold\" font-size=\"14.00\">spend_zero_mean_unit_variance</text>\n",
       "<text text-anchor=\"start\" x=\"580.97\" y=\"-352.5\" font-family=\"Helvetica,sans-Serif\" font-style=\"italic\" font-size=\"14.00\">Series</text>\n",
       "</g>\n",
       "<!-- spend_std_dev&#45;&gt;spend_zero_mean_unit_variance -->\n",
       "<g id=\"edge35\" class=\"edge\">\n",
       "<title>spend_std_dev&#45;&gt;spend_zero_mean_unit_variance</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M435.78,-404.26C444.72,-402.51 454.18,-400.65 463.87,-398.75\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"464.26,-402.24 473.39,-396.87 462.91,-395.37 464.26,-402.24\"/>\n",
       "</g>\n",
       "<!-- df_to_spreadsheet_build_result&#45;&gt;df_to_spreadsheet -->\n",
       "<g id=\"edge17\" class=\"edge\">\n",
       "<title>df_to_spreadsheet_build_result&#45;&gt;df_to_spreadsheet</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M1000.92,-138.22C1006.71,-136.85 1012.51,-135.47 1018.25,-134.12\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"1018.81,-137.58 1027.73,-131.87 1017.2,-130.77 1018.81,-137.58\"/>\n",
       "</g>\n",
       "<!-- df_to_avro_build_result&#45;&gt;df_to_avro -->\n",
       "<g id=\"edge18\" class=\"edge\">\n",
       "<title>df_to_avro_build_result&#45;&gt;df_to_avro</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M973.24,-235.65C996.81,-232.33 1021.85,-228.8 1044.49,-225.6\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"1044.83,-229.09 1054.24,-224.23 1043.85,-222.16 1044.83,-229.09\"/>\n",
       "</g>\n",
       "<!-- spend_zero_mean_unit_variance&#45;&gt;df_to_json_build_result -->\n",
       "<g id=\"edge6\" class=\"edge\">\n",
       "<title>spend_zero_mean_unit_variance&#45;&gt;df_to_json_build_result</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M719.09,-403.9C722.49,-406.63 725.7,-409.59 728.65,-412.8 766.67,-454.14 719.9,-494.21 757.65,-535.8 763.06,-541.76 769.37,-546.85 776.21,-551.2\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"774.1,-554.03 784.52,-555.94 777.57,-547.95 774.1,-554.03\"/>\n",
       "</g>\n",
       "<!-- spend_zero_mean_unit_variance&#45;&gt;df_to_database_build_result -->\n",
       "<g id=\"edge11\" class=\"edge\">\n",
       "<title>spend_zero_mean_unit_variance&#45;&gt;df_to_database_build_result</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M728.85,-390.56C738.51,-392 748.25,-393.45 757.87,-394.89\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"757.2,-398.32 767.61,-396.34 758.23,-391.4 757.2,-398.32\"/>\n",
       "</g>\n",
       "<!-- spend_zero_mean_unit_variance&#45;&gt;df_to_feather_build_result -->\n",
       "<g id=\"edge15\" class=\"edge\">\n",
       "<title>spend_zero_mean_unit_variance&#45;&gt;df_to_feather_build_result</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M715.23,-404.08C719.9,-406.77 724.4,-409.67 728.65,-412.8 746.62,-426.04 739.77,-440.44 757.65,-453.8 760.57,-455.98 763.61,-458.05 766.75,-460.02\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"764.71,-462.88 775.12,-464.84 768.2,-456.81 764.71,-462.88\"/>\n",
       "</g>\n",
       "<!-- spend_zero_mean_unit_variance&#45;&gt;df_to_parquet_build_result -->\n",
       "<g id=\"edge21\" class=\"edge\">\n",
       "<title>spend_zero_mean_unit_variance&#45;&gt;df_to_parquet_build_result</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M728.85,-353.04C740.1,-351.36 751.45,-349.67 762.6,-348.01\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"762.81,-351.52 772.18,-346.58 761.78,-344.59 762.81,-351.52\"/>\n",
       "</g>\n",
       "<!-- spend_zero_mean_unit_variance&#45;&gt;df_to_spreadsheet_build_result -->\n",
       "<g id=\"edge27\" class=\"edge\">\n",
       "<title>spend_zero_mean_unit_variance&#45;&gt;df_to_spreadsheet_build_result</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M719.09,-339.7C722.49,-336.97 725.7,-334.01 728.65,-330.8 766.67,-289.46 719.9,-249.39 757.65,-207.8 758.01,-207.4 758.38,-207.01 758.75,-206.62\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"760.96,-209.34 765.94,-199.98 756.21,-204.19 760.96,-209.34\"/>\n",
       "</g>\n",
       "<!-- spend_zero_mean_unit_variance&#45;&gt;df_to_avro_build_result -->\n",
       "<g id=\"edge31\" class=\"edge\">\n",
       "<title>spend_zero_mean_unit_variance&#45;&gt;df_to_avro_build_result</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M715.23,-339.52C719.9,-336.83 724.4,-333.93 728.65,-330.8 746.62,-317.56 739.77,-303.16 757.65,-289.8 762.98,-285.82 768.72,-282.21 774.7,-278.94\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"776.27,-282.06 783.61,-274.42 773.11,-275.82 776.27,-282.06\"/>\n",
       "</g>\n",
       "<!-- spend_zero_mean&#45;&gt;spend_zero_mean_unit_variance -->\n",
       "<g id=\"edge34\" class=\"edge\">\n",
       "<title>spend_zero_mean&#45;&gt;spend_zero_mean_unit_variance</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M446.66,-346.86C452.23,-347.76 457.94,-348.69 463.73,-349.62\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"463.02,-353.05 473.45,-351.19 464.14,-346.14 463.02,-353.05\"/>\n",
       "</g>\n",
       "<!-- spend_per_signup -->\n",
       "<g id=\"node18\" class=\"node\">\n",
       "<title>spend_per_signup</title>\n",
       "<path fill=\"#ffc857\" stroke=\"black\" d=\"M666.4,-321.6C666.4,-321.6 537.55,-321.6 537.55,-321.6 531.55,-321.6 525.55,-315.6 525.55,-309.6 525.55,-309.6 525.55,-270 525.55,-270 525.55,-264 531.55,-258 537.55,-258 537.55,-258 666.4,-258 666.4,-258 672.4,-258 678.4,-264 678.4,-270 678.4,-270 678.4,-309.6 678.4,-309.6 678.4,-315.6 672.4,-321.6 666.4,-321.6\"/>\n",
       "<text text-anchor=\"start\" x=\"536.35\" y=\"-298.5\" font-family=\"Helvetica,sans-Serif\" font-weight=\"bold\" font-size=\"14.00\">spend_per_signup</text>\n",
       "<text text-anchor=\"start\" x=\"580.97\" y=\"-270.5\" font-family=\"Helvetica,sans-Serif\" font-style=\"italic\" font-size=\"14.00\">Series</text>\n",
       "</g>\n",
       "<!-- spend_per_signup&#45;&gt;df_to_json_build_result -->\n",
       "<g id=\"edge5\" class=\"edge\">\n",
       "<title>spend_per_signup&#45;&gt;df_to_json_build_result</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M678.85,-300.02C697.62,-306.09 715.97,-315.68 728.65,-330.8 787.79,-401.3 698.96,-464.92 757.65,-535.8 762.88,-542.12 769.12,-547.46 775.98,-551.99\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"773.97,-554.86 784.37,-556.9 777.5,-548.82 773.97,-554.86\"/>\n",
       "</g>\n",
       "<!-- spend_per_signup&#45;&gt;df_to_database_build_result -->\n",
       "<g id=\"edge10\" class=\"edge\">\n",
       "<title>spend_per_signup&#45;&gt;df_to_database_build_result</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M678.87,-305.95C696.28,-311.92 713.96,-319.97 728.65,-330.8 746.62,-344.04 739.77,-358.44 757.65,-371.8 758.98,-372.79 760.33,-373.76 761.71,-374.71\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"759.48,-377.44 769.81,-379.82 763.22,-371.52 759.48,-377.44\"/>\n",
       "</g>\n",
       "<!-- spend_per_signup&#45;&gt;df_to_feather_build_result -->\n",
       "<g id=\"edge14\" class=\"edge\">\n",
       "<title>spend_per_signup&#45;&gt;df_to_feather_build_result</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M678.61,-301.02C697.16,-307.1 715.45,-316.44 728.65,-330.8 766.67,-372.14 719.9,-412.21 757.65,-453.8 760.65,-457.11 763.93,-460.15 767.43,-462.95\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"765.11,-465.59 775.29,-468.53 769.17,-459.89 765.11,-465.59\"/>\n",
       "</g>\n",
       "<!-- spend_per_signup&#45;&gt;df_to_parquet_build_result -->\n",
       "<g id=\"edge20\" class=\"edge\">\n",
       "<title>spend_per_signup&#45;&gt;df_to_parquet_build_result</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M678.88,-301.11C704.78,-304.97 734.36,-309.38 762.66,-313.6\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"761.95,-317.03 772.35,-315.04 762.98,-310.11 761.95,-317.03\"/>\n",
       "</g>\n",
       "<!-- spend_per_signup&#45;&gt;df_to_spreadsheet_build_result -->\n",
       "<g id=\"edge26\" class=\"edge\">\n",
       "<title>spend_per_signup&#45;&gt;df_to_spreadsheet_build_result</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M678.87,-273.65C696.28,-267.68 713.96,-259.63 728.65,-248.8 746.62,-235.56 739.77,-221.16 757.65,-207.8 758.98,-206.81 760.33,-205.84 761.71,-204.89\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"763.22,-208.08 769.81,-199.78 759.48,-202.16 763.22,-208.08\"/>\n",
       "</g>\n",
       "<!-- spend_per_signup&#45;&gt;df_to_avro_build_result -->\n",
       "<g id=\"edge30\" class=\"edge\">\n",
       "<title>spend_per_signup&#45;&gt;df_to_avro_build_result</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M678.88,-278.49C708.25,-274.11 742.36,-269.03 773.96,-264.32\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"774.15,-267.83 783.53,-262.89 773.12,-260.9 774.15,-267.83\"/>\n",
       "</g>\n",
       "<!-- _spend_mean_inputs -->\n",
       "<g id=\"node19\" class=\"node\">\n",
       "<title>_spend_mean_inputs</title>\n",
       "<polygon fill=\"#ffffff\" stroke=\"black\" stroke-dasharray=\"5,2\" points=\"121.1,-293.85 4.5,-293.85 4.5,-247.75 121.1,-247.75 121.1,-293.85\"/>\n",
       "<text text-anchor=\"start\" x=\"19.3\" y=\"-265.75\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">spend</text>\n",
       "<text text-anchor=\"start\" x=\"65.05\" y=\"-265.75\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">Series</text>\n",
       "</g>\n",
       "<!-- _spend_mean_inputs&#45;&gt;spend_mean -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>_spend_mean_inputs&#45;&gt;spend_mean</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M121.38,-270.8C127.72,-270.8 134.21,-270.8 140.65,-270.8\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"140.63,-274.3 150.63,-270.8 140.63,-267.3 140.63,-274.3\"/>\n",
       "</g>\n",
       "<!-- _avg_3wk_spend_inputs -->\n",
       "<g id=\"node20\" class=\"node\">\n",
       "<title>_avg_3wk_spend_inputs</title>\n",
       "<polygon fill=\"#ffffff\" stroke=\"black\" stroke-dasharray=\"5,2\" points=\"429.3,-512.85 312.7,-512.85 312.7,-466.75 429.3,-466.75 429.3,-512.85\"/>\n",
       "<text text-anchor=\"start\" x=\"327.5\" y=\"-484.75\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">spend</text>\n",
       "<text text-anchor=\"start\" x=\"373.25\" y=\"-484.75\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">Series</text>\n",
       "</g>\n",
       "<!-- _avg_3wk_spend_inputs&#45;&gt;avg_3wk_spend -->\n",
       "<g id=\"edge3\" class=\"edge\">\n",
       "<title>_avg_3wk_spend_inputs&#45;&gt;avg_3wk_spend</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M429.78,-480.72C458.1,-476.26 492.61,-470.84 523.21,-466.03\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"523.45,-469.53 532.79,-464.52 522.37,-462.62 523.45,-469.53\"/>\n",
       "</g>\n",
       "<!-- _df_to_json_build_result_inputs -->\n",
       "<g id=\"node21\" class=\"node\">\n",
       "<title>_df_to_json_build_result_inputs</title>\n",
       "<polygon fill=\"#ffffff\" stroke=\"black\" stroke-dasharray=\"5,2\" points=\"664.77,-743.6 539.17,-743.6 539.17,-676 664.77,-676 664.77,-743.6\"/>\n",
       "<text text-anchor=\"start\" x=\"553.72\" y=\"-715.5\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">signups</text>\n",
       "<text text-anchor=\"start\" x=\"608.85\" y=\"-715.5\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">Series</text>\n",
       "<text text-anchor=\"start\" x=\"558.6\" y=\"-693.5\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">spend</text>\n",
       "<text text-anchor=\"start\" x=\"608.85\" y=\"-693.5\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">Series</text>\n",
       "</g>\n",
       "<!-- _df_to_json_build_result_inputs&#45;&gt;df_to_json_build_result -->\n",
       "<g id=\"edge7\" class=\"edge\">\n",
       "<title>_df_to_json_build_result_inputs&#45;&gt;df_to_json_build_result</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M665.05,-691.47C685.66,-684.62 708.48,-676.2 728.65,-666.8 760.33,-652.05 793.81,-632.31 821.03,-615.07\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"822.57,-618.24 829.11,-609.91 818.8,-612.35 822.57,-618.24\"/>\n",
       "</g>\n",
       "<!-- _df_to_database_build_result_inputs -->\n",
       "<g id=\"node22\" class=\"node\">\n",
       "<title>_df_to_database_build_result_inputs</title>\n",
       "<polygon fill=\"#ffffff\" stroke=\"black\" stroke-dasharray=\"5,2\" points=\"664.77,-571.6 539.17,-571.6 539.17,-504 664.77,-504 664.77,-571.6\"/>\n",
       "<text text-anchor=\"start\" x=\"553.72\" y=\"-543.5\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">signups</text>\n",
       "<text text-anchor=\"start\" x=\"608.85\" y=\"-543.5\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">Series</text>\n",
       "<text text-anchor=\"start\" x=\"558.6\" y=\"-521.5\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">spend</text>\n",
       "<text text-anchor=\"start\" x=\"608.85\" y=\"-521.5\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">Series</text>\n",
       "</g>\n",
       "<!-- _df_to_database_build_result_inputs&#45;&gt;df_to_database_build_result -->\n",
       "<g id=\"edge12\" class=\"edge\">\n",
       "<title>_df_to_database_build_result_inputs&#45;&gt;df_to_database_build_result</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M665.21,-524.85C686.74,-518.3 710.09,-508.69 728.65,-494.8 746.52,-481.43 739.77,-467.16 757.65,-453.8 758.98,-452.81 760.33,-451.84 761.71,-450.89\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"763.22,-454.08 769.81,-445.78 759.48,-448.16 763.22,-454.08\"/>\n",
       "</g>\n",
       "<!-- _df_to_feather_build_result_inputs -->\n",
       "<g id=\"node23\" class=\"node\">\n",
       "<title>_df_to_feather_build_result_inputs</title>\n",
       "<polygon fill=\"#ffffff\" stroke=\"black\" stroke-dasharray=\"5,2\" points=\"664.77,-657.6 539.17,-657.6 539.17,-590 664.77,-590 664.77,-657.6\"/>\n",
       "<text text-anchor=\"start\" x=\"553.72\" y=\"-629.5\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">signups</text>\n",
       "<text text-anchor=\"start\" x=\"608.85\" y=\"-629.5\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">Series</text>\n",
       "<text text-anchor=\"start\" x=\"558.6\" y=\"-607.5\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">spend</text>\n",
       "<text text-anchor=\"start\" x=\"608.85\" y=\"-607.5\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">Series</text>\n",
       "</g>\n",
       "<!-- _df_to_feather_build_result_inputs&#45;&gt;df_to_feather_build_result -->\n",
       "<g id=\"edge16\" class=\"edge\">\n",
       "<title>_df_to_feather_build_result_inputs&#45;&gt;df_to_feather_build_result</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M665.23,-611.38C686.88,-604.87 710.31,-595.15 728.65,-580.8 747.39,-566.14 738.9,-550.45 757.65,-535.8 760.57,-533.52 763.61,-531.37 766.77,-529.33\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"768.39,-532.44 775.21,-524.33 764.82,-526.41 768.39,-532.44\"/>\n",
       "</g>\n",
       "<!-- _df_to_parquet_build_result_inputs -->\n",
       "<g id=\"node24\" class=\"node\">\n",
       "<title>_df_to_parquet_build_result_inputs</title>\n",
       "<polygon fill=\"#ffffff\" stroke=\"black\" stroke-dasharray=\"5,2\" points=\"664.77,-239.6 539.17,-239.6 539.17,-172 664.77,-172 664.77,-239.6\"/>\n",
       "<text text-anchor=\"start\" x=\"553.72\" y=\"-211.5\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">signups</text>\n",
       "<text text-anchor=\"start\" x=\"608.85\" y=\"-211.5\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">Series</text>\n",
       "<text text-anchor=\"start\" x=\"558.6\" y=\"-189.5\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">spend</text>\n",
       "<text text-anchor=\"start\" x=\"608.85\" y=\"-189.5\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">Series</text>\n",
       "</g>\n",
       "<!-- _df_to_parquet_build_result_inputs&#45;&gt;df_to_parquet_build_result -->\n",
       "<g id=\"edge22\" class=\"edge\">\n",
       "<title>_df_to_parquet_build_result_inputs&#45;&gt;df_to_parquet_build_result</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M665.21,-218.75C686.74,-225.3 710.09,-234.91 728.65,-248.8 746.52,-262.17 739.77,-276.44 757.65,-289.8 759.7,-291.33 761.81,-292.81 763.97,-294.23\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"762.08,-297.18 772.45,-299.35 765.7,-291.19 762.08,-297.18\"/>\n",
       "</g>\n",
       "<!-- _spend_std_dev_inputs -->\n",
       "<g id=\"node25\" class=\"node\">\n",
       "<title>_spend_std_dev_inputs</title>\n",
       "<polygon fill=\"#ffffff\" stroke=\"black\" stroke-dasharray=\"5,2\" points=\"266.7,-439.85 150.1,-439.85 150.1,-393.75 266.7,-393.75 266.7,-439.85\"/>\n",
       "<text text-anchor=\"start\" x=\"164.9\" y=\"-411.75\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">spend</text>\n",
       "<text text-anchor=\"start\" x=\"210.65\" y=\"-411.75\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">Series</text>\n",
       "</g>\n",
       "<!-- _spend_std_dev_inputs&#45;&gt;spend_std_dev -->\n",
       "<g id=\"edge24\" class=\"edge\">\n",
       "<title>_spend_std_dev_inputs&#45;&gt;spend_std_dev</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M266.93,-416.8C276.01,-416.8 285.52,-416.8 294.94,-416.8\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"294.82,-420.3 304.82,-416.8 294.82,-413.3 294.82,-420.3\"/>\n",
       "</g>\n",
       "<!-- _df_to_spreadsheet_build_result_inputs -->\n",
       "<g id=\"node26\" class=\"node\">\n",
       "<title>_df_to_spreadsheet_build_result_inputs</title>\n",
       "<polygon fill=\"#ffffff\" stroke=\"black\" stroke-dasharray=\"5,2\" points=\"664.77,-67.6 539.17,-67.6 539.17,0 664.77,0 664.77,-67.6\"/>\n",
       "<text text-anchor=\"start\" x=\"553.72\" y=\"-39.5\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">signups</text>\n",
       "<text text-anchor=\"start\" x=\"608.85\" y=\"-39.5\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">Series</text>\n",
       "<text text-anchor=\"start\" x=\"558.6\" y=\"-17.5\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">spend</text>\n",
       "<text text-anchor=\"start\" x=\"608.85\" y=\"-17.5\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">Series</text>\n",
       "</g>\n",
       "<!-- _df_to_spreadsheet_build_result_inputs&#45;&gt;df_to_spreadsheet_build_result -->\n",
       "<g id=\"edge28\" class=\"edge\">\n",
       "<title>_df_to_spreadsheet_build_result_inputs&#45;&gt;df_to_spreadsheet_build_result</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M665.05,-52.13C685.66,-58.98 708.48,-67.4 728.65,-76.8 760.33,-91.55 793.81,-111.29 821.03,-128.53\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"818.8,-131.25 829.11,-133.69 822.57,-125.36 818.8,-131.25\"/>\n",
       "</g>\n",
       "<!-- _df_to_avro_build_result_inputs -->\n",
       "<g id=\"node27\" class=\"node\">\n",
       "<title>_df_to_avro_build_result_inputs</title>\n",
       "<polygon fill=\"#ffffff\" stroke=\"black\" stroke-dasharray=\"5,2\" points=\"664.77,-153.6 539.17,-153.6 539.17,-86 664.77,-86 664.77,-153.6\"/>\n",
       "<text text-anchor=\"start\" x=\"553.72\" y=\"-125.5\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">signups</text>\n",
       "<text text-anchor=\"start\" x=\"608.85\" y=\"-125.5\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">Series</text>\n",
       "<text text-anchor=\"start\" x=\"558.6\" y=\"-103.5\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">spend</text>\n",
       "<text text-anchor=\"start\" x=\"608.85\" y=\"-103.5\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">Series</text>\n",
       "</g>\n",
       "<!-- _df_to_avro_build_result_inputs&#45;&gt;df_to_avro_build_result -->\n",
       "<g id=\"edge32\" class=\"edge\">\n",
       "<title>_df_to_avro_build_result_inputs&#45;&gt;df_to_avro_build_result</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M665.23,-132.22C686.88,-138.73 710.31,-148.45 728.65,-162.8 747.39,-177.46 738.9,-193.15 757.65,-207.8 763.07,-212.04 768.96,-215.85 775.12,-219.28\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"773.16,-222.21 783.65,-223.67 776.36,-215.98 773.16,-222.21\"/>\n",
       "</g>\n",
       "<!-- _spend_zero_mean_inputs -->\n",
       "<g id=\"node28\" class=\"node\">\n",
       "<title>_spend_zero_mean_inputs</title>\n",
       "<polygon fill=\"#ffffff\" stroke=\"black\" stroke-dasharray=\"5,2\" points=\"266.7,-366.85 150.1,-366.85 150.1,-320.75 266.7,-320.75 266.7,-366.85\"/>\n",
       "<text text-anchor=\"start\" x=\"164.9\" y=\"-338.75\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">spend</text>\n",
       "<text text-anchor=\"start\" x=\"210.65\" y=\"-338.75\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">Series</text>\n",
       "</g>\n",
       "<!-- _spend_zero_mean_inputs&#45;&gt;spend_zero_mean -->\n",
       "<g id=\"edge37\" class=\"edge\">\n",
       "<title>_spend_zero_mean_inputs&#45;&gt;spend_zero_mean</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M266.93,-340.58C272.52,-340.26 278.28,-339.94 284.07,-339.62\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"283.93,-343.13 293.72,-339.07 283.54,-336.14 283.93,-343.13\"/>\n",
       "</g>\n",
       "<!-- _spend_per_signup_inputs -->\n",
       "<g id=\"node29\" class=\"node\">\n",
       "<title>_spend_per_signup_inputs</title>\n",
       "<polygon fill=\"#ffffff\" stroke=\"black\" stroke-dasharray=\"5,2\" points=\"433.8,-284.6 308.2,-284.6 308.2,-217 433.8,-217 433.8,-284.6\"/>\n",
       "<text text-anchor=\"start\" x=\"322.75\" y=\"-256.5\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">signups</text>\n",
       "<text text-anchor=\"start\" x=\"377.87\" y=\"-256.5\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">Series</text>\n",
       "<text text-anchor=\"start\" x=\"327.62\" y=\"-234.5\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">spend</text>\n",
       "<text text-anchor=\"start\" x=\"377.87\" y=\"-234.5\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">Series</text>\n",
       "</g>\n",
       "<!-- _spend_per_signup_inputs&#45;&gt;spend_per_signup -->\n",
       "<g id=\"edge38\" class=\"edge\">\n",
       "<title>_spend_per_signup_inputs&#45;&gt;spend_per_signup</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M434.27,-261.41C458.83,-265.59 487.48,-270.47 514.03,-274.99\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"513.32,-278.42 523.77,-276.65 514.5,-271.52 513.32,-278.42\"/>\n",
       "</g>\n",
       "<!-- input -->\n",
       "<g id=\"node30\" class=\"node\">\n",
       "<title>input</title>\n",
       "<polygon fill=\"#ffffff\" stroke=\"black\" stroke-dasharray=\"5,2\" points=\"89.8,-349.85 35.8,-349.85 35.8,-311.75 89.8,-311.75 89.8,-349.85\"/>\n",
       "<text text-anchor=\"middle\" x=\"62.8\" y=\"-325.75\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">input</text>\n",
       "</g>\n",
       "<!-- function -->\n",
       "<g id=\"node31\" class=\"node\">\n",
       "<title>function</title>\n",
       "<path fill=\"#b4d8e4\" stroke=\"black\" d=\"M86.35,-405.85C86.35,-405.85 39.25,-405.85 39.25,-405.85 33.25,-405.85 27.25,-399.85 27.25,-393.85 27.25,-393.85 27.25,-379.75 27.25,-379.75 27.25,-373.75 33.25,-367.75 39.25,-367.75 39.25,-367.75 86.35,-367.75 86.35,-367.75 92.35,-367.75 98.35,-373.75 98.35,-379.75 98.35,-379.75 98.35,-393.85 98.35,-393.85 98.35,-399.85 92.35,-405.85 86.35,-405.85\"/>\n",
       "<text text-anchor=\"middle\" x=\"62.8\" y=\"-381.75\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">function</text>\n",
       "</g>\n",
       "<!-- output -->\n",
       "<g id=\"node32\" class=\"node\">\n",
       "<title>output</title>\n",
       "<path fill=\"#ffc857\" stroke=\"black\" d=\"M81.1,-461.85C81.1,-461.85 44.5,-461.85 44.5,-461.85 38.5,-461.85 32.5,-455.85 32.5,-449.85 32.5,-449.85 32.5,-435.75 32.5,-435.75 32.5,-429.75 38.5,-423.75 44.5,-423.75 44.5,-423.75 81.1,-423.75 81.1,-423.75 87.1,-423.75 93.1,-429.75 93.1,-435.75 93.1,-435.75 93.1,-449.85 93.1,-449.85 93.1,-455.85 87.1,-461.85 81.1,-461.85\"/>\n",
       "<text text-anchor=\"middle\" x=\"62.8\" y=\"-437.75\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">output</text>\n",
       "</g>\n",
       "<!-- materializer -->\n",
       "<g id=\"node33\" class=\"node\">\n",
       "<title>materializer</title>\n",
       "<path fill=\"#ffffff\" stroke=\"black\" d=\"M109.6,-518.18C109.6,-520.31 88.62,-522.04 62.8,-522.04 36.98,-522.04 16,-520.31 16,-518.18 16,-518.18 16,-483.42 16,-483.42 16,-481.29 36.98,-479.56 62.8,-479.56 88.62,-479.56 109.6,-481.29 109.6,-483.42 109.6,-483.42 109.6,-518.18 109.6,-518.18\"/>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M109.6,-518.18C109.6,-516.05 88.62,-514.32 62.8,-514.32 36.98,-514.32 16,-516.05 16,-518.18\"/>\n",
       "<text text-anchor=\"middle\" x=\"62.8\" y=\"-495.75\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">materializer</text>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.graphs.Digraph at 0x2b06a471e40>"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "materializers = [\n",
    "    # materialize the dataframe to a parquet file\n",
    "    to.parquet(\n",
    "        dependencies=output_columns,\n",
    "        id=\"df_to_parquet\",\n",
    "        file=\"./df.parquet\",\n",
    "        combine=df_builder,\n",
    "    ),\n",
    "    # materialize the dataframe to a feather file\n",
    "    to.feather(\n",
    "        dependencies=output_columns,\n",
    "        id=\"df_to_feather\",\n",
    "        file=\"./df.feather\",\n",
    "        combine=df_builder,\n",
    "    ),\n",
    "    # materialize the dataframe to a json file\n",
    "    to.json(\n",
    "        dependencies=output_columns,\n",
    "        id=\"df_to_json\",\n",
    "        file=\"./df.json\",\n",
    "        combine=df_builder,\n",
    "    ),\n",
    "    # materialize the dataframe to an avro file\n",
    "    to.avro(\n",
    "        dependencies=output_columns,\n",
    "        id=\"df_to_avro\",\n",
    "        file=\"./df.avro\",\n",
    "        combine=df_builder,\n",
    "    ),\n",
    "    # materialize the dataframe to a database\n",
    "    to.database(\n",
    "        dependencies=output_columns,\n",
    "        id=\"df_to_database\",\n",
    "        table_name=\"test\",\n",
    "        connection=\"sqlite:///df.db\",\n",
    "        if_table_exists=\"append\",\n",
    "        combine=df_builder,\n",
    "    ),\n",
    "    #materialize the dataframe to a spreadsheet file\n",
    "    to.spreadsheet(\n",
    "        dependencies=output_columns,\n",
    "        id=\"df_to_spreadsheet\",\n",
    "        workbook=\"./df.xlsx\",\n",
    "        worksheet=\"Sheet1\",\n",
    "        combine=df_builder,\n",
    "    ),\n",
    "]\n",
    "# Visualize what is happening\n",
    "dr.visualize_materialization(\n",
    "    *materializers,\n",
    "    additional_vars=output_columns,\n",
    "    inputs=initial_columns,\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-05T16:36:56.565384Z",
     "start_time": "2023-10-05T16:36:56.531421Z"
    }
   },
   "outputs": [],
   "source": [
    "# Materialize a result, i.e. execute the DAG!\n",
    "materialization_results, additional_outputs = dr.materialize(\n",
    "    *materializers,\n",
    "    additional_vars=[\n",
    "        \"df_to_parquet_build_result\",\n",
    "        \"df_to_feather_build_result\",\n",
    "        \"df_to_json_build_result\",\n",
    "        \"df_to_avro_build_result\",\n",
    "        \"df_to_database_build_result\",\n",
    "        \"df_to_spreadsheet_build_result\",\n",
    "    ],  # because combine is used, we can get that result here.\n",
    "    inputs=initial_columns,\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-05T16:36:57.122715Z",
     "start_time": "2023-10-05T16:36:57.101770Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'df_to_parquet': {'file_metadata': {'size': 1609,\n",
       "   'path': './df.parquet',\n",
       "   'last_modified': 1711363433.0819426,\n",
       "   'timestamp': 1711343633.081942,\n",
       "   'scheme': '',\n",
       "   'notes': ''},\n",
       "  'dataframe_metadata': {'rows': 6,\n",
       "   'columns': 5,\n",
       "   'column_names': ['spend',\n",
       "    'signups',\n",
       "    'avg_3wk_spend',\n",
       "    'spend_per_signup',\n",
       "    'spend_zero_mean_unit_variance'],\n",
       "   'datatypes': ['Int64', 'Int64', 'Float64', 'Float64', 'Float64']}},\n",
       " 'df_to_feather': {'file_metadata': {'size': 1696,\n",
       "   'path': './df.feather',\n",
       "   'last_modified': 1711363433.0829415,\n",
       "   'timestamp': 1711343633.082941,\n",
       "   'scheme': '',\n",
       "   'notes': ''},\n",
       "  'dataframe_metadata': {'rows': 6,\n",
       "   'columns': 5,\n",
       "   'column_names': ['spend',\n",
       "    'signups',\n",
       "    'avg_3wk_spend',\n",
       "    'spend_per_signup',\n",
       "    'spend_zero_mean_unit_variance'],\n",
       "   'datatypes': ['Int64', 'Int64', 'Float64', 'Float64', 'Float64']}},\n",
       " 'df_to_json': {'file_metadata': {'size': 657,\n",
       "   'path': './df.json',\n",
       "   'last_modified': 1711363433.0839424,\n",
       "   'timestamp': 1711343633.083942,\n",
       "   'scheme': '',\n",
       "   'notes': ''},\n",
       "  'dataframe_metadata': {'rows': 6,\n",
       "   'columns': 5,\n",
       "   'column_names': ['spend',\n",
       "    'signups',\n",
       "    'avg_3wk_spend',\n",
       "    'spend_per_signup',\n",
       "    'spend_zero_mean_unit_variance'],\n",
       "   'datatypes': ['Int64', 'Int64', 'Float64', 'Float64', 'Float64']}},\n",
       " 'df_to_avro': {'file_metadata': {'size': 517,\n",
       "   'path': './df.avro',\n",
       "   'last_modified': 1711363433.0849397,\n",
       "   'timestamp': 1711343633.084939,\n",
       "   'scheme': '',\n",
       "   'notes': ''},\n",
       "  'dataframe_metadata': {'rows': 6,\n",
       "   'columns': 5,\n",
       "   'column_names': ['spend',\n",
       "    'signups',\n",
       "    'avg_3wk_spend',\n",
       "    'spend_per_signup',\n",
       "    'spend_zero_mean_unit_variance'],\n",
       "   'datatypes': ['Int64', 'Int64', 'Float64', 'Float64', 'Float64']}},\n",
       " 'df_to_database': {'file_metadata': {'size': None,\n",
       "   'path': 'test',\n",
       "   'last_modified': 1711363433.3330674,\n",
       "   'timestamp': 1711343633.333067,\n",
       "   'scheme': '',\n",
       "   'notes': 'File metadata is unsupported for scheme:  or path: test does not exist.'},\n",
       "  'dataframe_metadata': {'rows': 6,\n",
       "   'columns': 5,\n",
       "   'column_names': ['spend',\n",
       "    'signups',\n",
       "    'avg_3wk_spend',\n",
       "    'spend_per_signup',\n",
       "    'spend_zero_mean_unit_variance'],\n",
       "   'datatypes': ['Int64', 'Int64', 'Float64', 'Float64', 'Float64']}},\n",
       " 'df_to_spreadsheet': {'file_metadata': {'size': 6503,\n",
       "   'path': './df.xlsx',\n",
       "   'last_modified': 1711363433.3686314,\n",
       "   'timestamp': 1711343633.369631,\n",
       "   'scheme': '',\n",
       "   'notes': ''},\n",
       "  'dataframe_metadata': {'rows': 6,\n",
       "   'columns': 5,\n",
       "   'column_names': ['spend',\n",
       "    'signups',\n",
       "    'avg_3wk_spend',\n",
       "    'spend_per_signup',\n",
       "    'spend_zero_mean_unit_variance'],\n",
       "   'datatypes': ['Int64', 'Int64', 'Float64', 'Float64', 'Float64']}}}"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "materialization_results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-05T16:36:57.826266Z",
     "start_time": "2023-10-05T16:36:57.805459Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div><style>\n",
       ".dataframe > thead > tr,\n",
       ".dataframe > tbody > tr {\n",
       "  text-align: right;\n",
       "  white-space: pre-wrap;\n",
       "}\n",
       "</style>\n",
       "<small>shape: (6, 5)</small><table border=\"1\" class=\"dataframe\"><thead><tr><th>spend</th><th>signups</th><th>avg_3wk_spend</th><th>spend_per_signup</th><th>spend_zero_mean_unit_variance</th></tr><tr><td>i64</td><td>i64</td><td>f64</td><td>f64</td><td>f64</td></tr></thead><tbody><tr><td>10</td><td>1</td><td>null</td><td>10.0</td><td>-1.064405</td></tr><tr><td>10</td><td>10</td><td>null</td><td>1.0</td><td>-1.064405</td></tr><tr><td>20</td><td>50</td><td>13.333333</td><td>0.4</td><td>-0.483821</td></tr><tr><td>40</td><td>100</td><td>23.333333</td><td>0.4</td><td>0.677349</td></tr><tr><td>40</td><td>200</td><td>33.333333</td><td>0.2</td><td>0.677349</td></tr><tr><td>50</td><td>400</td><td>43.333333</td><td>0.125</td><td>1.257934</td></tr></tbody></table></div>"
      ],
      "text/plain": [
       "shape: (6, 5)\n",
       "┌───────┬─────────┬───────────────┬──────────────────┬───────────────────────────────┐\n",
       "│ spend ┆ signups ┆ avg_3wk_spend ┆ spend_per_signup ┆ spend_zero_mean_unit_variance │\n",
       "│ ---   ┆ ---     ┆ ---           ┆ ---              ┆ ---                           │\n",
       "│ i64   ┆ i64     ┆ f64           ┆ f64              ┆ f64                           │\n",
       "╞═══════╪═════════╪═══════════════╪══════════════════╪═══════════════════════════════╡\n",
       "│ 10    ┆ 1       ┆ null          ┆ 10.0             ┆ -1.064405                     │\n",
       "│ 10    ┆ 10      ┆ null          ┆ 1.0              ┆ -1.064405                     │\n",
       "│ 20    ┆ 50      ┆ 13.333333     ┆ 0.4              ┆ -0.483821                     │\n",
       "│ 40    ┆ 100     ┆ 23.333333     ┆ 0.4              ┆ 0.677349                      │\n",
       "│ 40    ┆ 200     ┆ 33.333333     ┆ 0.2              ┆ 0.677349                      │\n",
       "│ 50    ┆ 400     ┆ 43.333333     ┆ 0.125            ┆ 1.257934                      │\n",
       "└───────┴─────────┴───────────────┴──────────────────┴───────────────────────────────┘"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "additional_outputs[\"df_to_parquet_build_result\"]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-05T16:36:58.919203Z",
     "start_time": "2023-10-05T16:36:58.869761Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div><style>\n",
       ".dataframe > thead > tr,\n",
       ".dataframe > tbody > tr {\n",
       "  text-align: right;\n",
       "  white-space: pre-wrap;\n",
       "}\n",
       "</style>\n",
       "<small>shape: (6, 5)</small><table border=\"1\" class=\"dataframe\"><thead><tr><th>spend</th><th>signups</th><th>avg_3wk_spend</th><th>spend_per_signup</th><th>spend_zero_mean_unit_variance</th></tr><tr><td>i64</td><td>i64</td><td>f64</td><td>f64</td><td>f64</td></tr></thead><tbody><tr><td>10</td><td>1</td><td>null</td><td>10.0</td><td>-1.064405</td></tr><tr><td>10</td><td>10</td><td>null</td><td>1.0</td><td>-1.064405</td></tr><tr><td>20</td><td>50</td><td>13.333333</td><td>0.4</td><td>-0.483821</td></tr><tr><td>40</td><td>100</td><td>23.333333</td><td>0.4</td><td>0.677349</td></tr><tr><td>40</td><td>200</td><td>33.333333</td><td>0.2</td><td>0.677349</td></tr><tr><td>50</td><td>400</td><td>43.333333</td><td>0.125</td><td>1.257934</td></tr></tbody></table></div>"
      ],
      "text/plain": [
       "shape: (6, 5)\n",
       "┌───────┬─────────┬───────────────┬──────────────────┬───────────────────────────────┐\n",
       "│ spend ┆ signups ┆ avg_3wk_spend ┆ spend_per_signup ┆ spend_zero_mean_unit_variance │\n",
       "│ ---   ┆ ---     ┆ ---           ┆ ---              ┆ ---                           │\n",
       "│ i64   ┆ i64     ┆ f64           ┆ f64              ┆ f64                           │\n",
       "╞═══════╪═════════╪═══════════════╪══════════════════╪═══════════════════════════════╡\n",
       "│ 10    ┆ 1       ┆ null          ┆ 10.0             ┆ -1.064405                     │\n",
       "│ 10    ┆ 10      ┆ null          ┆ 1.0              ┆ -1.064405                     │\n",
       "│ 20    ┆ 50      ┆ 13.333333     ┆ 0.4              ┆ -0.483821                     │\n",
       "│ 40    ┆ 100     ┆ 23.333333     ┆ 0.4              ┆ 0.677349                      │\n",
       "│ 40    ┆ 200     ┆ 33.333333     ┆ 0.2              ┆ 0.677349                      │\n",
       "│ 50    ┆ 400     ┆ 43.333333     ┆ 0.125            ┆ 1.257934                      │\n",
       "└───────┴─────────┴───────────────┴──────────────────┴───────────────────────────────┘"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "additional_outputs[\"df_to_feather_build_result\"]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-05T16:37:01.766669Z",
     "start_time": "2023-10-05T16:37:01.705286Z"
    },
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div><style>\n",
       ".dataframe > thead > tr,\n",
       ".dataframe > tbody > tr {\n",
       "  text-align: right;\n",
       "  white-space: pre-wrap;\n",
       "}\n",
       "</style>\n",
       "<small>shape: (6, 5)</small><table border=\"1\" class=\"dataframe\"><thead><tr><th>spend</th><th>signups</th><th>avg_3wk_spend</th><th>spend_per_signup</th><th>spend_zero_mean_unit_variance</th></tr><tr><td>i64</td><td>i64</td><td>f64</td><td>f64</td><td>f64</td></tr></thead><tbody><tr><td>10</td><td>1</td><td>null</td><td>10.0</td><td>-1.064405</td></tr><tr><td>10</td><td>10</td><td>null</td><td>1.0</td><td>-1.064405</td></tr><tr><td>20</td><td>50</td><td>13.333333</td><td>0.4</td><td>-0.483821</td></tr><tr><td>40</td><td>100</td><td>23.333333</td><td>0.4</td><td>0.677349</td></tr><tr><td>40</td><td>200</td><td>33.333333</td><td>0.2</td><td>0.677349</td></tr><tr><td>50</td><td>400</td><td>43.333333</td><td>0.125</td><td>1.257934</td></tr></tbody></table></div>"
      ],
      "text/plain": [
       "shape: (6, 5)\n",
       "┌───────┬─────────┬───────────────┬──────────────────┬───────────────────────────────┐\n",
       "│ spend ┆ signups ┆ avg_3wk_spend ┆ spend_per_signup ┆ spend_zero_mean_unit_variance │\n",
       "│ ---   ┆ ---     ┆ ---           ┆ ---              ┆ ---                           │\n",
       "│ i64   ┆ i64     ┆ f64           ┆ f64              ┆ f64                           │\n",
       "╞═══════╪═════════╪═══════════════╪══════════════════╪═══════════════════════════════╡\n",
       "│ 10    ┆ 1       ┆ null          ┆ 10.0             ┆ -1.064405                     │\n",
       "│ 10    ┆ 10      ┆ null          ┆ 1.0              ┆ -1.064405                     │\n",
       "│ 20    ┆ 50      ┆ 13.333333     ┆ 0.4              ┆ -0.483821                     │\n",
       "│ 40    ┆ 100     ┆ 23.333333     ┆ 0.4              ┆ 0.677349                      │\n",
       "│ 40    ┆ 200     ┆ 33.333333     ┆ 0.2              ┆ 0.677349                      │\n",
       "│ 50    ┆ 400     ┆ 43.333333     ┆ 0.125            ┆ 1.257934                      │\n",
       "└───────┴─────────┴───────────────┴──────────────────┴───────────────────────────────┘"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "additional_outputs[\"df_to_json_build_result\"]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div><style>\n",
       ".dataframe > thead > tr,\n",
       ".dataframe > tbody > tr {\n",
       "  text-align: right;\n",
       "  white-space: pre-wrap;\n",
       "}\n",
       "</style>\n",
       "<small>shape: (6, 5)</small><table border=\"1\" class=\"dataframe\"><thead><tr><th>spend</th><th>signups</th><th>avg_3wk_spend</th><th>spend_per_signup</th><th>spend_zero_mean_unit_variance</th></tr><tr><td>i64</td><td>i64</td><td>f64</td><td>f64</td><td>f64</td></tr></thead><tbody><tr><td>10</td><td>1</td><td>null</td><td>10.0</td><td>-1.064405</td></tr><tr><td>10</td><td>10</td><td>null</td><td>1.0</td><td>-1.064405</td></tr><tr><td>20</td><td>50</td><td>13.333333</td><td>0.4</td><td>-0.483821</td></tr><tr><td>40</td><td>100</td><td>23.333333</td><td>0.4</td><td>0.677349</td></tr><tr><td>40</td><td>200</td><td>33.333333</td><td>0.2</td><td>0.677349</td></tr><tr><td>50</td><td>400</td><td>43.333333</td><td>0.125</td><td>1.257934</td></tr></tbody></table></div>"
      ],
      "text/plain": [
       "shape: (6, 5)\n",
       "┌───────┬─────────┬───────────────┬──────────────────┬───────────────────────────────┐\n",
       "│ spend ┆ signups ┆ avg_3wk_spend ┆ spend_per_signup ┆ spend_zero_mean_unit_variance │\n",
       "│ ---   ┆ ---     ┆ ---           ┆ ---              ┆ ---                           │\n",
       "│ i64   ┆ i64     ┆ f64           ┆ f64              ┆ f64                           │\n",
       "╞═══════╪═════════╪═══════════════╪══════════════════╪═══════════════════════════════╡\n",
       "│ 10    ┆ 1       ┆ null          ┆ 10.0             ┆ -1.064405                     │\n",
       "│ 10    ┆ 10      ┆ null          ┆ 1.0              ┆ -1.064405                     │\n",
       "│ 20    ┆ 50      ┆ 13.333333     ┆ 0.4              ┆ -0.483821                     │\n",
       "│ 40    ┆ 100     ┆ 23.333333     ┆ 0.4              ┆ 0.677349                      │\n",
       "│ 40    ┆ 200     ┆ 33.333333     ┆ 0.2              ┆ 0.677349                      │\n",
       "│ 50    ┆ 400     ┆ 43.333333     ┆ 0.125            ┆ 1.257934                      │\n",
       "└───────┴─────────┴───────────────┴──────────────────┴───────────────────────────────┘"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "additional_outputs[\"df_to_avro_build_result\"]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div><style>\n",
       ".dataframe > thead > tr,\n",
       ".dataframe > tbody > tr {\n",
       "  text-align: right;\n",
       "  white-space: pre-wrap;\n",
       "}\n",
       "</style>\n",
       "<small>shape: (6, 5)</small><table border=\"1\" class=\"dataframe\"><thead><tr><th>spend</th><th>signups</th><th>avg_3wk_spend</th><th>spend_per_signup</th><th>spend_zero_mean_unit_variance</th></tr><tr><td>i64</td><td>i64</td><td>f64</td><td>f64</td><td>f64</td></tr></thead><tbody><tr><td>10</td><td>1</td><td>null</td><td>10.0</td><td>-1.064405</td></tr><tr><td>10</td><td>10</td><td>null</td><td>1.0</td><td>-1.064405</td></tr><tr><td>20</td><td>50</td><td>13.333333</td><td>0.4</td><td>-0.483821</td></tr><tr><td>40</td><td>100</td><td>23.333333</td><td>0.4</td><td>0.677349</td></tr><tr><td>40</td><td>200</td><td>33.333333</td><td>0.2</td><td>0.677349</td></tr><tr><td>50</td><td>400</td><td>43.333333</td><td>0.125</td><td>1.257934</td></tr></tbody></table></div>"
      ],
      "text/plain": [
       "shape: (6, 5)\n",
       "┌───────┬─────────┬───────────────┬──────────────────┬───────────────────────────────┐\n",
       "│ spend ┆ signups ┆ avg_3wk_spend ┆ spend_per_signup ┆ spend_zero_mean_unit_variance │\n",
       "│ ---   ┆ ---     ┆ ---           ┆ ---              ┆ ---                           │\n",
       "│ i64   ┆ i64     ┆ f64           ┆ f64              ┆ f64                           │\n",
       "╞═══════╪═════════╪═══════════════╪══════════════════╪═══════════════════════════════╡\n",
       "│ 10    ┆ 1       ┆ null          ┆ 10.0             ┆ -1.064405                     │\n",
       "│ 10    ┆ 10      ┆ null          ┆ 1.0              ┆ -1.064405                     │\n",
       "│ 20    ┆ 50      ┆ 13.333333     ┆ 0.4              ┆ -0.483821                     │\n",
       "│ 40    ┆ 100     ┆ 23.333333     ┆ 0.4              ┆ 0.677349                      │\n",
       "│ 40    ┆ 200     ┆ 33.333333     ┆ 0.2              ┆ 0.677349                      │\n",
       "│ 50    ┆ 400     ┆ 43.333333     ┆ 0.125            ┆ 1.257934                      │\n",
       "└───────┴─────────┴───────────────┴──────────────────┴───────────────────────────────┘"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "additional_outputs[\"df_to_database_build_result\"]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div><style>\n",
       ".dataframe > thead > tr,\n",
       ".dataframe > tbody > tr {\n",
       "  text-align: right;\n",
       "  white-space: pre-wrap;\n",
       "}\n",
       "</style>\n",
       "<small>shape: (6, 5)</small><table border=\"1\" class=\"dataframe\"><thead><tr><th>spend</th><th>signups</th><th>avg_3wk_spend</th><th>spend_per_signup</th><th>spend_zero_mean_unit_variance</th></tr><tr><td>i64</td><td>i64</td><td>f64</td><td>f64</td><td>f64</td></tr></thead><tbody><tr><td>10</td><td>1</td><td>null</td><td>10.0</td><td>-1.064405</td></tr><tr><td>10</td><td>10</td><td>null</td><td>1.0</td><td>-1.064405</td></tr><tr><td>20</td><td>50</td><td>13.333333</td><td>0.4</td><td>-0.483821</td></tr><tr><td>40</td><td>100</td><td>23.333333</td><td>0.4</td><td>0.677349</td></tr><tr><td>40</td><td>200</td><td>33.333333</td><td>0.2</td><td>0.677349</td></tr><tr><td>50</td><td>400</td><td>43.333333</td><td>0.125</td><td>1.257934</td></tr></tbody></table></div>"
      ],
      "text/plain": [
       "shape: (6, 5)\n",
       "┌───────┬─────────┬───────────────┬──────────────────┬───────────────────────────────┐\n",
       "│ spend ┆ signups ┆ avg_3wk_spend ┆ spend_per_signup ┆ spend_zero_mean_unit_variance │\n",
       "│ ---   ┆ ---     ┆ ---           ┆ ---              ┆ ---                           │\n",
       "│ i64   ┆ i64     ┆ f64           ┆ f64              ┆ f64                           │\n",
       "╞═══════╪═════════╪═══════════════╪══════════════════╪═══════════════════════════════╡\n",
       "│ 10    ┆ 1       ┆ null          ┆ 10.0             ┆ -1.064405                     │\n",
       "│ 10    ┆ 10      ┆ null          ┆ 1.0              ┆ -1.064405                     │\n",
       "│ 20    ┆ 50      ┆ 13.333333     ┆ 0.4              ┆ -0.483821                     │\n",
       "│ 40    ┆ 100     ┆ 23.333333     ┆ 0.4              ┆ 0.677349                      │\n",
       "│ 40    ┆ 200     ┆ 33.333333     ┆ 0.2              ┆ 0.677349                      │\n",
       "│ 50    ┆ 400     ┆ 43.333333     ┆ 0.125            ┆ 1.257934                      │\n",
       "└───────┴─────────┴───────────────┴──────────────────┴───────────────────────────────┘"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "additional_outputs[\"df_to_spreadsheet_build_result\"]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
